package com.skyline.imagine.storage;

import java.io.File;
import java.io.IOException;

import org.apache.commons.io.FilenameUtils;
import org.csource.common.MyException;
import org.csource.fastdfs.StorageClient;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;

import com.skyline.imagine.exception.FileDownloadException;
import com.skyline.imagine.exception.FileStoreException;
import com.skyline.imagine.exception.StorageUnreachableException;

public class FastDFSFileOperator implements InitializingBean {
	private String config;
	private String imageGroupName;

	public void setConfig(String config) {
		this.config = config;
	}

	public void setImageGroupName(String imageGroupName) {
		this.imageGroupName = imageGroupName;
	}

	/**
	 * 
	 * @param file
	 * @return results[0]: the group name to store the file<br/>
	 *         results[1]: the new created filename
	 * @throws Exception
	 */
	public String[] uploadFile(File file) throws StorageUnreachableException {
		String filePath = file.getPath();
		String ext = FilenameUtils.getExtension(filePath);

		return uploadFile(file, ext);
	}
	
	/**
	 * 
	 * @param file
	 * @param ext
	 * @return results[0]: the group name to store the file<br/>
	 *         results[1]: the new created filename
	 * @throws Exception
	 */
	public String[] uploadFile(File file, String ext) throws StorageUnreachableException {
		Assert.notNull(file, "Can't upload null file");
		Assert.isTrue(file.isFile(), "Can't upload an directory");

		StorageClient client = StorageClientFactory.getStorageClient(imageGroupName);

		String filePath = file.getPath();

		try {
			return client.upload_file(filePath, ext, null);
		} catch (IOException e) {
			throw new FileStoreException(e);
		} catch (MyException e) {
			throw new FileStoreException(e);
		}
	}

	/**
	 * 
	 * @param file
	 * @param ext
	 * 
	 * @return results[0]: the group name to store the file<br/>
	 *         results[1]: the new created filename
	 * @throws Exception
	 */
	public String[] uploadFile(byte[] file, String ext) throws StorageUnreachableException {
		StorageClient client = StorageClientFactory.getStorageClient(imageGroupName);

		try {
			return client.upload_file(file, ext, null);
		} catch (IOException e) {
			throw new FileStoreException(e);
		} catch (MyException e) {
			throw new FileStoreException(e);
		}

	}

	/**
	 * 
	 * @param remoteFile
	 * @param localFile
	 * @throws Exception
	 */
	public void downloadFile(String remoteFile, String localFile) throws StorageUnreachableException {
		StorageClient client = StorageClientFactory.getStorageClient(imageGroupName);

		int result;

		try {
			result = client.download_file(imageGroupName, remoteFile, localFile);
		} catch (IOException e) {
			throw new FileDownloadException(e);
		} catch (MyException e) {
			throw new FileDownloadException(e);
		}

		if (result != 0) {
			throw new FileDownloadException("download file:" + remoteFile + " from FastDFS failed");
		}
	}

	/**
	 * 
	 * @param remoteFile
	 * @return fileData
	 * @throws Exception
	 */
	public byte[] downloadFile(String remoteFile) throws StorageUnreachableException {
		StorageClient client = StorageClientFactory.getStorageClient(imageGroupName);

		byte[] result = null;
		try {
			result = client.download_file(imageGroupName, remoteFile);
		} catch (IOException e) {
			throw new FileDownloadException(e);
		} catch (MyException e) {
			throw new FileDownloadException(e);
		}

		if (result == null || result.length == 0) {
			throw new FileDownloadException("download file:" + remoteFile + " from FastDFS failed");
		}

		return result;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		Assert.notNull(config, "Config File Path Cannot Be null");
		Resource configResource = new ClassPathResource(config);
		StorageClientFactory.init(configResource);
	}
}
